package com.mindbox.mueblesalpes.negocio.cliente;

import com.mindbox.mueblesalpes.negocio.entity.Ciudad;
import com.mindbox.mueblesalpes.negocio.entity.Cliente;
import com.mindbox.mueblesalpes.negocio.entity.TipoDocumento;
import com.mindbox.mueblesalpes.negocio.entity.TipoUsuario;
import com.mindbox.mueblesalpes.negocio.entity.Usuario;
import com.mindbox.mueblesalpes.negocio.exception.TiendaException;
import com.mindbox.mueblesalpes.negocio.persistence.PersistenciaLocal;
import java.util.HashMap;
import java.util.List;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * EJB de persistencia
 * @author Diana Carolina
 */
@Stateless
@DeclareRoles({"Administrador", "Gerente"})
public class ClienteServiceBean implements ClienteServiceLocal {
    
    @PersistenceContext
    private EntityManager em;
     @EJB
    private PersistenciaLocal persistencia;

     /**
      *
      */
     public ClienteServiceBean(){
    }
    /**
     * Método que realiza la creación de un cliente
     * @return
     */
    public boolean crearCliente(Cliente cliente){
       try{
        persistencia.create(cliente);
        return true;
       }catch(Exception ex){
           throw new TiendaException(ex.getMessage());
       }
    }
    /**
     * Realiza la búsqueda de los clientes de la aplicación
     * @param cliente
     * @return Listado de los clientes de la aplicación
     */
    public List<Cliente> buscarCliente(Cliente cliente){
        return persistencia.findAll(Cliente.class);
    }
    /**
     *
     * @return
     */
    public List<Cliente> mostrarClientes(){
        return persistencia.findAll(Cliente.class);
    }
    /**
     * Realiza la eliminación de un cliente
     * @param cliente: datos del cliente a ser eliminado
     */
    @RolesAllowed({"Administrador"})
    public void eliminarCliente(Cliente cliente){
        try{
            if(cliente != null){
                persistencia.delete(cliente);
            }
        }catch(Exception e){
            throw new TiendaException("Se presento un error realizando la eliminación de un cliente");
        }
    }
    /**
     * Realiza la actualización de los datos de un cliente
     * @param cliente datos del cliente a actualizar
     */
   
    public void editarCliente(Cliente cliente) {
        try {
            if (cliente != null) {
                persistencia.update(cliente);
            }
        } catch (Exception e) {
            throw new TiendaException("No fué posible actualizar los datos del cliente");
        }
    }
    /**
     * Realiza la consulta de los datos de un cliente
     * @param cliente datos del cliente a consultar
     * @return resultado de la búsqueda
     */
    
    public List<Cliente> consultarCliente(Cliente cliente){
        List<Cliente> listadoClientes = null;
        HashMap<String, String> parameters = new HashMap<String, String>();
        HashMap<String, Enum> parametersEnum = new HashMap<String, Enum>();

        try {
            if(cliente.getNumeroDocumento() == null){
                cliente.setNumeroDocumento("");
            }
            if(cliente.getNombreCompleto() == null){
                cliente.setNombreCompleto("");
            }
            if(cliente.getTelefonoResidencia() == null){
                cliente.setTelefonoResidencia("");
            }
            if(cliente.getDireccion() == null){
                cliente.setDireccion("");
            }
            if(cliente.getEmail() == null){
                cliente.setEmail("");
            }
            parametersEnum.put("tipoDocumento", cliente.getTipoDocumento());
            parameters.put("numeroDocumento", cliente.getNumeroDocumento());
            parameters.put("nombreCompleto", cliente.getNombreCompleto());
            parameters.put("telefonoResidencia", cliente.getTelefonoResidencia());
            parameters.put("direccion", cliente.getDireccion());
            parameters.put("email", cliente.getEmail());
            listadoClientes = persistencia.findByFilterEnum("Cliente", parameters, parametersEnum);

        } catch (Exception e) {
            throw new TiendaException("Se presentó un error consultando clientes");
        }
        return listadoClientes;
    }

    /**
     * Realiza la búsqueda de los datos de logueo de un usuario
     * @param usuario: datos del usuario a ser buscado
     * @return Cliente
     */
    @Override
    public Cliente buscarClienteLogin(Usuario usuario) {
        try {
            String txtQuery = "SELECT c FROM Cliente c where c.usuario.usuario = '" + usuario.getUsuario()+"'";
            Query query = em.createQuery(txtQuery);
            return (Cliente) query.getSingleResult();
		} catch(NoResultException e){
			throw new TiendaException("No se encontró el usuario");
		}catch(NonUniqueResultException e){
			throw new TiendaException("Existe un usuario repetido en la base de datos");
		}
    }
    /**
     * Realiza la búsqueda de un usuario
     * @param usuario: datos del usuario a buscar
     * @return: objeto  usuario
     */
    @Override

    public Usuario buscarUsuario(Usuario usuario) {
        try {
             List usuarios = persistencia.findAll(Usuario.class);
             if(usuarios == null || usuarios.isEmpty()){
                 crearUsuarios();
             }
             //TODO pendiente la seguridad y validación de password JAAS
            String txtQuery = "SELECT p FROM Usuario p where p.usuario = '" + usuario.getUsuario() +"' ";
            Query query = em.createQuery(txtQuery);
			return (Usuario) query.getSingleResult();
		} catch(NoResultException e){
			throw new TiendaException("No se encontró el usuario");
		}catch(NonUniqueResultException e){
			throw new TiendaException("Existe un usuario repetido en la base de datos");
		}
    }

    /**
     * Realiza la carga inicial de usuariosS
     */
    
    private void crearUsuarios() {
        try {
            Usuario usrAdmin1 = new Usuario();
            usrAdmin1.setUsuario("admin");
            usrAdmin1.setPwd("admin");
            usrAdmin1.setTipoUsuario(TipoUsuario.ADMINISTRADOR);
            em.persist(usrAdmin1);

            Usuario usrAdmin2 = new Usuario();
            usrAdmin2.setUsuario("ADMINISTRADOR");
            usrAdmin2.setPwd("admin");
            usrAdmin2.setTipoUsuario(TipoUsuario.ADMINISTRADOR);
            em.persist(usrAdmin2);

            Usuario usr = new Usuario();
            usr.setUsuario("mindbox");
            usr.setPwd("mindbox");
            usr.setTipoUsuario(TipoUsuario.CLIENTE);
            Cliente cliente = new Cliente();
            cliente.setCelular("300556677");
            cliente.setNombreCompleto("Harry Plotter");
            cliente.setTipoDocumento(TipoDocumento.CEDULA);
            cliente.setNumeroDocumento("80202020220");
            cliente.setUsuario(usr);
            em.persist(cliente);
        } catch (Exception e) {
            e.printStackTrace();
            throw new TiendaException("Error al crear los datos iniciales "+e.getMessage());
        }
    }

    @Override
    public Usuario buscarUsuarioPorLogin(Usuario usuario) {
        try {
            if(usuario == null){
                throw new TiendaException("El usuario es nulo");
            }
            String txtQuery = "SELECT p FROM Usuario p where p.usuario = '" + usuario.getUsuario() +"' ";
            Query query = em.createQuery(txtQuery);
			return (Usuario) query.getSingleResult();
		} catch(NoResultException e){
			return null;
		}catch(NonUniqueResultException e){
			throw new TiendaException("Existe un usuario repetido en la base de datos");
		}
    }

    @Override
    public Cliente buscarClientePorId(Cliente cliente) {
        try {
            if(cliente.getIdCliente() == null){
                return null;
            }
            String txtQuery = "SELECT c FROM Cliente c where c.idCliente = " + cliente.getIdCliente().longValue() + "";
            Query query = em.createQuery(txtQuery);
			return (Cliente) query.getSingleResult();
		} catch(NoResultException e){
			return null;
		}catch(NonUniqueResultException e){
			throw new TiendaException("Existe un cliente repetido en la base de datos");
		}
    }

}
